package io.renren.utils;

import com.alibaba.druid.wall.violation.ErrorCode;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 解析sql语句
 */
@Component
public class SqlParse {

    /**
     * 存储匹编译好的数据类型的正则
     */
    private final static Pattern[] dataTypePatterns = {
            Pattern.compile("TINYINT", Pattern.CASE_INSENSITIVE),
            Pattern.compile("INT", Pattern.CASE_INSENSITIVE),
            Pattern.compile("BIGINT", Pattern.CASE_INSENSITIVE),
            Pattern.compile("FLOAT", Pattern.CASE_INSENSITIVE),
            Pattern.compile("DOUBLE", Pattern.CASE_INSENSITIVE),
            Pattern.compile("DECIMAL", Pattern.CASE_INSENSITIVE),
            Pattern.compile("DATE", Pattern.CASE_INSENSITIVE),
            Pattern.compile("DATETIME", Pattern.CASE_INSENSITIVE),
            Pattern.compile("CHAR", Pattern.CASE_INSENSITIVE),
            Pattern.compile("VARCHAR", Pattern.CASE_INSENSITIVE),
            Pattern.compile("TEXT", Pattern.CASE_INSENSITIVE),
    };

    /**
     * 存储匹编译好的额外类型的正则
     */
    private final static Pattern[] extraPatterns = {
            Pattern.compile("auto_increment", Pattern.CASE_INSENSITIVE)
    };

    /**
     * 存储匹配编译好的主键的正则
     */
    private final static Pattern primaryKeyPattern = Pattern.compile("PRIMARY KEY", Pattern.CASE_INSENSITIVE);

    /**
     * 存储匹配编译好的评论的正则
     */
    private final static Pattern[] columnCommentPattern = {
            Pattern.compile("(?<=\").*?(?=\")", Pattern.CASE_INSENSITIVE),
            Pattern.compile("(?<=\').*?(?=\')", Pattern.CASE_INSENSITIVE),
    };

    private List<Map<String, String>> columnsInfo;

    private Map<String, String> tableInfo;

    public List<Map<String, String>> getColumnsInfo() {
        if (columnsInfo == null) {
            throw new RuntimeException("列信息未获取");
        }
        return columnsInfo;
    }

    public Map<String, String> getTableInfo() {
        if (tableInfo == null) {
            throw new RuntimeException("表信息未获取");
        }
        return tableInfo;
    }

    /**
     * 解析sql建表语句, 分析每个字段, 表格所具有的信息
     * @param sqlTable
     */
    public void parseSql(String sqlTable) {
        columnsInfo = new ArrayList<>();
        tableInfo = new HashMap<>();
        // 切割建表
        int start = sqlTable.indexOf("("), end = sqlTable.lastIndexOf(")");
        String sqlSentences = sqlTable.substring(start + 1, end);
        parseTable(sqlTable);
        // 分析字段的语句
        parseSentences(sqlSentences);
    }

    private void parseTable(String sqlTable) {
        String table = sqlTable.substring(0, sqlTable.indexOf("(")) + sqlTable.substring(sqlTable.lastIndexOf(")") + 1);
        System.out.println(table);
        // 获取表名
        List<String> split = Arrays.asList(table.split(" "));
        //split = split.stream().filter(StringUtils::isBlank).collect(Collectors.toList());
        split = split.stream().filter(e -> !StringUtils.isBlank(e)).collect(Collectors.toList());
        String tableName = split.get(2).trim();
        // 获取表的评价
        String tableComment = split.get(4);
        tableInfo.put("tableName", tableName);
        tableInfo.put("tableComment", tableComment);

        System.out.println(tableInfo.toString());
    }

    /**
     * 切割sql关于字段的语句,分析其中包含关于字段的信息
     * @param sqlSentences
     *
     */
    public void parseSentences(String sqlSentences) {
        // 切割每一句话
        List<String> split = Arrays.asList(sqlSentences.split(","));
        List<String> sqlSentence = split.stream().map(String::trim).collect(Collectors.toList());

        sqlSentence.forEach(System.out::println);
        // 分析每一句话
        for (String s : sqlSentence) {
            Map<String, String> res = new HashMap<>();
            // 获取列名
            res.put( "columnName", s.substring(0, s.indexOf(" ")) );
            // 获取数据类型
            String dataType = null;
            for (Pattern p : dataTypePatterns) {
                Matcher matcher = p.matcher(s);
                if (matcher.find()) dataType = p.pattern().toLowerCase();
            }
            res.put("dataType", dataType);
            // 获取额外信息
            String EXTRA = null;
            for (Pattern p : extraPatterns) {
                Matcher matcher = p.matcher(s);
                if (matcher.find()) EXTRA = p.pattern().toLowerCase();
            }
            res.put("EXTRA", EXTRA);
            // 获取是否是主键
            String columnKey = null;
            {
                Matcher matcher = primaryKeyPattern.matcher(s);
                if (matcher.find()) columnKey = "PRI";
            }
            res.put("columnKey", columnKey);
            String columnComment = null;
            // 获取字段的评价
            for (Pattern p : columnCommentPattern) {
                Matcher matcher = p.matcher(s);
                if (matcher.find()) columnComment = matcher.group();
            }
            res.put("columnComment", columnComment);
            // 存储每一句话匹配到的信息
            columnsInfo.add(res);
        }
    }
}
